package glock

import (
	"encoding/json"
	"github.com/pkg/errors"
	"log"
	"net"
)

type GClient struct {
	conn net.Conn
}

func NewGClient() *GClient {
	return &GClient{}
}

// Connect connects to the server
func (g *GClient) Connect(address string) error {
	conn, err := net.Dial("tcp", address)
	if err != nil {
		return err
	}

	g.conn = conn

	return nil
}

func (g *GClient) Lock(key string, expire int64) (bool, error) {

	req := LockReq{
		Key:    key,
		Expire: expire,
	}

	bs, err := json.Marshal(req)

	if err != nil {
		return false, err
	}

	// 发送请求
	cmd := &Cmder{
		CmdType: Cmd_Lock,
		Datas:   bs,
	}

	marshal, err := json.Marshal(cmd)

	if err != nil {
		return false, errors.Wrap(err, "json marshal error")
	}

	log.Println("send:", string(marshal))

	_, err = g.conn.Write(marshal)

	if err != nil {
		return false, errors.Wrap(err, "write error")
	}

	// 接收响应
	buf := make([]byte, 1024)
	n, err := g.conn.Read(buf)

	if err != nil {
		return false, errors.Wrap(err, "read error")
	}

	result := Result{}

	err = json.Unmarshal(buf[:n], &result)

	if err != nil {
		return false, errors.Wrap(err, "json unmarshal error")
	}

	if result.ErrStr != "" {
		return false, errors.New(result.ErrStr)
	}

	return result.Success, nil
}

// Unlock unlocks the key
func (g *GClient) Unlock(key string) error {

	req := UnlockReq{
		Key: key,
	}

	bs, err := json.Marshal(req)

	if err != nil {
		return err
	}

	// 发送请求
	cmd := &Cmder{
		CmdType: Cmd_Unlock,
		Datas:   bs,
	}

	marshal, err := json.Marshal(cmd)

	if err != nil {
		return errors.Wrap(err, "json marshal error")
	}

	_, err = g.conn.Write(marshal)

	if err != nil {
		return errors.Wrap(err, "write error")
	}

	// 接收响应

	buf := make([]byte, 1024)
	_, err = g.conn.Read(buf)

	if err != nil {
		return errors.Wrap(err, "read error")
	}

	return nil
}
